﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using ScrapySharp.Extensions;
using ScrapySharp.Html.Dom;
using ScrapySharp.Network;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace HotCopperUserScanService
{
    /// <summary>
    /// This class will take an accept a bunch of HTML and parse out the required details
    /// The acceptance criteria are listed here:
    /// 
    /// 1. Given a block of HTML it should find the latest posts from a given date
    /// 2. For those posts the text of the post and date and time should be extracted 
    /// 3. The text of the post should be scanned for all know asx stock codes and they should be reported.
    /// 
    /// </summary>
    public class Parser
    {
        public static object ExtractPosts()
        {
            throw new NotImplementedException();
        }

        public static IEnumerable<Post> ExtractPosts(string html, string userName, IStockForumBrowser browser, int maxPosts, Collection<string> messages)
        {
            var document = HDocument.Parse(html);
            var posts = new List<Post>(maxPosts);

            var selected = document.CssSelect("li.post-item       ");

            foreach (var post in selected.Take(maxPosts))
            {
                //navigate to each post to extra the vital information

                var linkToPost = post.Children.Where(c => c.Name == "div").SelectMany(c => c.Children)
                                .Where(c => c.Name == "h3").SelectMany(c => c.Children)
                                .First(c => c.Name == "a").Attributes["href"];

                var url = "http://hotcopper.com.au/" + linkToPost;
                var page = browser.NavigateToPage(new Uri(url));
                if (page != null)
                {
                    posts.Add(new Post()
                    {
                        DateTime = page.DateTime,
                        Content = page.Content,
                        Username = userName,
                        Uri = page.Uri,
                        Code = page.Code,
                        FirstPrice = page.FirstPrice
                    });
                }
                else
                {
                    messages.Add("Unable to get content from " + url);
                }
            }

            return posts;
        }
    }

    public class Post : INotifyPropertyChanged
    {
        private DateTime _dateTime;
        private string _content;
        private string _username;
        private string _uri;
        private string _code;
        private string _firstPrice;
        private Single _target;

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }

        public DateTime DateTime { get { return _dateTime; } set { _dateTime = value; this.NotifyPropertyChanged("DateTime"); } }
        public string Content { get { return _content; } set { _content = value; this.NotifyPropertyChanged("Content"); } }
        public string Username { get { return _username; } set { _username = value; this.NotifyPropertyChanged("Username"); } }
        public string Uri { get { return _uri; } set { _uri = value; this.NotifyPropertyChanged("Uri"); } }
        public string Code { get { return _code; } set { _code = value; this.NotifyPropertyChanged("Code"); } }
        public string FirstPrice { get { return _firstPrice; } set { _firstPrice = value; this.NotifyPropertyChanged("FirstPrice"); } }
        public Single Target { get { return _target; } set { _target = value; this.NotifyPropertyChanged("Target"); } }

        public string Id { get; set; }
    }
}
